
#include "all.h"

extern unsigned char FNTBL[256];

NFN_STRUCT *_parse_filename(struct NFN_STRUCT *EDI)
{
	// EDI IS NFN_STRUCT
	// (LENGTH IS ALREADY SET, AND TEXT IS THERE)


	// RETURNS:
	// 	NFN_STRUCT

	unsigned char m;
	unsigned char c;
	unsigned char *p;

	EDI->NFN_PATHLEN = 0;
	EDI->NFN_PRIMLEN = 0;
	EDI->NFN_EXTLEN = 0;
	EDI->NFN_FLAGS = 0;
	EDI->NFN_TYPE = 0;
	EDI->reserved1 = 0;

	int ECX = EDI->NFN_TOTAL_LENGTH;
	p = &EDI->NFN_TEXT[0];
	*(int *)(p+ECX) = 0;	// ZERO AT END
	p += ECX - 1;		// p IS AT THE LAST CHAR OF TOKEN

	// SCAN FORWARDS LOOKING FOR AMBIGUOUS CHARACTERS

	// OK, NOW SCAN BACKWARDS FOR EXTENT OR PATH STUFF
	// SKIP TRAILING SPACES
	while (ECX)
	{
	    c = *p--;
	    if (c != ' ')
		    goto L31;
	    EDI->NFN_TOTAL_LENGTH = --ECX;
	}
	goto L9;

L31:
	m = FNTBL[c];
	--ECX;
	if (!(m & (FNTBL_PATH_SEPARATOR | FNTBL_DOT | FNTBL_AMBIGUOUS)))
	{
	    if (ECX)
	    {	c = *p--;
		goto L31;
	    }
	    goto DO_PRIMARY2;
	}
	if (m & FNTBL_AMBIGUOUS)
	{
	    EDI->NFN_FLAGS |= NFN_AMBIGUOUS;
	    if (ECX)
	    {	c = *p--;
		goto L31;
	    }
	    goto DO_PRIMARY2;
	}
	if (m & FNTBL_DOT)
	{
	    // GOT A '.', SO STORE EXTENSION LENGTH
	    int EAX = EDI->NFN_TOTAL_LENGTH;
	    EDI->NFN_FLAGS |= NFN_EXT_SPECIFIED;
	    EAX -= ECX;
	    if (EAX == 1 && !FORCE_PATH)
	    {
		// JUST A DOT, REMOVE IT...
		--EDI->NFN_TOTAL_LENGTH;
	    }
	    else
	    {
		EDI->NFN_EXTLEN = EAX;
	    }

	    // NOW LOOK ONLY FOR END-OF-PRIMARY...
	    if (!ECX)
		    goto L9;
	    while (1)
	    {
		unsigned char m = FNTBL[*p--];
		if (--ECX == 0)
		{
		    if (m & (FNTBL_PATH_SEPARATOR | FNTBL_AMBIGUOUS))
		    {
			if (!(m & FNTBL_PATH_SEPARATOR))
			    EDI->NFN_FLAGS |= NFN_AMBIGUOUS;
			break;
		    }
		    goto DO_PRIMARY2;
		}
		if (m & FNTBL_PATH_SEPARATOR)
		    break;
		if (m & FNTBL_AMBIGUOUS)
		    EDI->NFN_FLAGS |= NFN_AMBIGUOUS;
	    }
	}
DO_PRIMARY1:
	++ECX;
DO_PRIMARY:
	//++p;
DO_PRIMARY2:
	EDI->NFN_PRIMLEN = EDI->NFN_TOTAL_LENGTH - EDI->NFN_EXTLEN - ECX;
	if (EDI->NFN_PRIMLEN)
	    EDI->NFN_FLAGS |= NFN_PRIM_SPECIFIED;

	// NOW, ECX IS # OF BYTES IN A PATH-SPEC
	if (ECX)
	{
	    EDI->NFN_PATHLEN = ECX;
	    EDI->NFN_FLAGS |= NFN_PATH_SPECIFIED;
	}
L9:
	// ALL DONE, CONGRATS!
	if (FORCE_PATH)
	{
	    // IF PRIMLEN OR EXTLEN !=0, MAKE THEM ZERO AND ADD A \ AT END

	    EDI->NFN_FLAGS &= ~(NFN_PRIM_SPECIFIED | NFN_EXT_SPECIFIED);

	    if (EDI->NFN_PRIMLEN + EDI->NFN_EXTLEN)
	    {
		EDI->NFN_PATHLEN += EDI->NFN_PRIMLEN + EDI->NFN_EXTLEN + 1;
		EDI->NFN_PRIMLEN = 0;
		EDI->NFN_EXTLEN = 0;
		EDI->NFN_TEXT[EDI->NFN_PATHLEN - 1] = '\\';
		EDI->NFN_TOTAL_LENGTH += 1;
		EDI->NFN_FLAGS |= NFN_PATH_SPECIFIED;
	    }
	}
	return EDI;
}

void _force_path(struct NFN_STRUCT *EDI)
{
	    // IF PRIMLEN OR EXTLEN !=0, MAKE THEM ZERO AND ADD A \ AT END

	    EDI->NFN_FLAGS &= ~(NFN_PRIM_SPECIFIED | NFN_EXT_SPECIFIED);

	    if (EDI->NFN_PRIMLEN + EDI->NFN_EXTLEN)
	    {
		EDI->NFN_PATHLEN += EDI->NFN_PRIMLEN + EDI->NFN_EXTLEN + 1;
		EDI->NFN_PRIMLEN = 0;
		EDI->NFN_EXTLEN = 0;
		EDI->NFN_TEXT[EDI->NFN_PATHLEN - 1] = '\\';
		EDI->NFN_TOTAL_LENGTH += 1;
		EDI->NFN_FLAGS |= NFN_PATH_SPECIFIED;
	    }
}

// MUST BE IN DATA SEGMENT, AS WE MODIFY IT...

unsigned char FNTBL[256] =
{
	// ILLEGAL HPFS FILENAME CHARS ARE:

	//  0-1FH, " * + , / : ; < = > ? [ \ ] |

	// WE ALLOW PATH SEPARATORS \ / :
	// WE ALLOW AMBIGUOUS CHARS ? *


	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 00 NUL
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 01 SOH
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 02
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 03
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 04
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 05
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 06
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 07 BEL
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 08 BS
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 09 TAB
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 0A LF
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 0B
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 0C
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 0D CR
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 0E
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 0F
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 10
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 11
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 12
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 13
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 14
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 15
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 16
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 17
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 18
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 19
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 1A
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 1B ESC
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 1C
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 1D
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 1E
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 1F

	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 20 SPACE
	0,		// 21 !
	FNTBL_ILLEGAL,	// 22 "
	0,		// 23 #
	0,		// 24 $
	0,		// 25 %
	0,		// 26 &
	0,		// 27 '
	SYMTBL_ILLEGAL,	// 28 (
	SYMTBL_ILLEGAL,	// 29 )	;ILLEGAL IN FILE NAMES IF '(' OVERLAY FOUND
	FNTBL_AMBIGUOUS | SYMTBL_ILLEGAL,	// 2A *
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 2B +
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 2C ,
	0,		// 2D -
	FNTBL_DOT,	// 2E .
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 2F /	;ILLEGAL FOR MSCMDLIN SUPPORT...

	IS_NUMERIC,	// 30 0
	IS_NUMERIC,	// 31 1
	IS_NUMERIC,	// 32 2
	IS_NUMERIC,	// 33 3
	IS_NUMERIC,	// 34 4
	IS_NUMERIC,	// 35 5
	IS_NUMERIC,	// 36 6
	IS_NUMERIC,	// 37 7
	IS_NUMERIC,	// 38 8
	IS_NUMERIC,	// 39 9
	FNTBL_PATH_SEPARATOR | SYMTBL_ILLEGAL,	// 3A :
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 3B ;
	FNTBL_ILLEGAL,	// 3C <
	FNTBL_ILLEGAL | SYMTBL_ILLEGAL,	// 3D =
	FNTBL_ILLEGAL,	// 3E >
	FNTBL_AMBIGUOUS,	// 3F ?

	0,		// 40 @
	IS_ALPHA,	// 41 A
	IS_ALPHA,	// 42 B
	IS_ALPHA,	// 43 C
	IS_ALPHA,	// 44 D
	IS_ALPHA,	// 45 E
	IS_ALPHA,	// 46 F
	IS_ALPHA,	// 47 G
	IS_ALPHA,	// 48 H
	IS_ALPHA,	// 49 I
	IS_ALPHA,	// 4A J
	IS_ALPHA,	// 4B K
	IS_ALPHA,	// 4C L
	IS_ALPHA,	// 4D M
	IS_ALPHA,	// 4E N
	IS_ALPHA,	// 4F O

	IS_ALPHA,	// 50 P
	IS_ALPHA,	// 51 Q
	IS_ALPHA,	// 52 R
	IS_ALPHA,	// 53 S
	IS_ALPHA,	// 54 T
	IS_ALPHA,	// 55 U
	IS_ALPHA,	// 56 V
	IS_ALPHA,	// 57 W
	IS_ALPHA,	// 58 X
	IS_ALPHA,	// 59 Y
	IS_ALPHA,	// 5A Z
	FNTBL_ILLEGAL,	// 5B [
	FNTBL_PATH_SEPARATOR,	// 5C '\\'
	FNTBL_ILLEGAL,	// 5D ]
	0,		// 5E ^
	0,		// 5F _

	0,		// 60 `
	IS_ALPHA,	// 61 a
	IS_ALPHA,	// 62 b
	IS_ALPHA,	// 63 c
	IS_ALPHA,	// 64 d
	IS_ALPHA,	// 65 e
	IS_ALPHA,	// 66 f
	IS_ALPHA,	// 67 g
	IS_ALPHA,	// 68 h
	IS_ALPHA,	// 69 i
	IS_ALPHA,	// 6A j
	IS_ALPHA,	// 6B k
	IS_ALPHA,	// 6C l
	IS_ALPHA,	// 6D m
	IS_ALPHA,	// 6E n
	IS_ALPHA,	// 6F o

	IS_ALPHA,	// 70 p
	IS_ALPHA,	// 71 q
	IS_ALPHA,	// 72 r
	IS_ALPHA,	// 73 s
	IS_ALPHA,	// 74 t
	IS_ALPHA,	// 75 u
	IS_ALPHA,	// 76 v
	IS_ALPHA,	// 77 w
	IS_ALPHA,	// 78 x
	IS_ALPHA,	// 79 y
	IS_ALPHA,	// 7A z
	0,		// 7B {
	FNTBL_ILLEGAL,	// 7C |
	0,		// 7D }
	0,		// 7E ~
	0,		// 7F
};

